package com.liusand.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.jwt.JWTUtil;
import com.alibaba.fastjson.JSON;
import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.sdk.service.dysmsapi20170525.AsyncClient;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsResponse;
import com.google.gson.Gson;
import com.liusand.exception.SendSmsException;
import com.liusand.exception.UserException;
import com.liusand.mapper.UserMapper;
import com.liusand.pojo.User;
import com.liusand.service.UserService;
import com.liusand.vo.UserVo;
import darabonba.core.client.ClientOverrideConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author :liusha
 * packageName :com.liusand.service.impl
 * fileName :UserServiceImpl
 * creationTime :2022/11/30 19:02
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Override
    public boolean sendMsg(String phone) {
        Random random = new Random();
        int verifyCode = random.nextInt(900000) + 100000;
        if("18065888835".equals(phone)){
            log.info(verifyCode + "");
            redisTemplate.opsForValue().set("code_"+phone, verifyCode + "", 10, TimeUnit.MINUTES);
            return true;
        }

        String accessKeyId = "LTAI5tDBeNg2zhfFRnpWAv3b";
        String accessKeySecret = "uQHQTLF14rM84YM29Qz3yhj6wanxWN";

        StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
                .accessKeyId(accessKeyId)
                .accessKeySecret(accessKeySecret)
                .build());

        AsyncClient client = AsyncClient.builder()
                .region("cn-hangzhou")
                .credentialsProvider(provider)
                .overrideConfiguration(
                        ClientOverrideConfiguration.create()
                                .setEndpointOverride("dysmsapi.aliyuncs.com")
                                .setConnectTimeout(Duration.ofSeconds(30))
                )
                .build();

        SendSmsRequest sendSmsRequest = SendSmsRequest.builder()
                .signName("惟手熟尔")
                .templateCode("SMS_262090079")
                .phoneNumbers(phone)
                .templateParam("{\"code\":\"" + verifyCode + "\"}")
                // Request-level configuration rewrite, can set Http request parameters, etc.
                // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
                .build();
        CompletableFuture<SendSmsResponse> response = client.sendSms(sendSmsRequest);
        // Synchronously get the return value of the API request
        try {
            SendSmsResponse resp = response.get();
            String s = new Gson().toJson(resp);
            log.info(s);
            if(!"OK".equals(resp.getBody().getCode())){
                return false;
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }finally {
            client.close();
            redisTemplate.opsForValue().set("code_"+phone, verifyCode + "", 10, TimeUnit.MINUTES);
            log.info("{}", verifyCode);
        }
        return true;
    }

    @Override
    public UserVo login(String phone, String code) {
        if(!StringUtils.hasText(phone) || !StringUtils.hasText(code)){
            throw new UserException("传入的参数不能为空");
        }
        String s = (String) redisTemplate.opsForValue().get("code_" + phone);
        if(!StringUtils.hasText(s)){
            throw new UserException("验证码失效");
        }
        if(!s.equals(code)){
            throw new UserException("验证码错误");
        }
        User user = userMapper.findUserByPhone(phone);
        if(user == null){
            user = new User();
            user.setPhone(phone);
            user.setStatus(1);
            user.setId(IdUtil.getSnowflakeNextIdStr());
            Integer re = userMapper.insert(user);
            if(re != 1){
                throw new UserException("创建账号失败");
            }
            user = userMapper.findUserByPhone(phone);
        }
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user, userVo);
        Map<String,Object> payload = new HashMap<String,Object>();
        payload.put("phone", user.getPhone());
        payload.put("id", user.getId());
        String key = "QWER";
        String token = JWTUtil.createToken(payload, key.getBytes());
        userVo.setToken(token);
        redisTemplate.opsForValue().set("token_"+token, JSON.toJSONString(user), 30, TimeUnit.MINUTES);
        return userVo;
    }

    @Override
    public boolean loginOut(String token) {
        return redisTemplate.delete("token_" + token);
    }
}
